/**
 * 对象深拷贝
 */
export const deepClone = (data:any) => {
    const type = getObjType(data)
    let obj:any
    if (type === 'array') {
        obj = []
    } else if (type === 'object') {
        obj = {}
    } else {
        //不再具有下一层次
        return data
    }
    if (type === 'array') {
        for (let i = 0, len = data.length; i < len; i++) {
            obj.push(deepClone(data[i]))
        }
    } else if (type === 'object') {
        for (const key in data) {
            obj[key] = deepClone(data[key])
        }
    }
    return obj
}

export const getObjType = (obj:any) => {
    const toString = Object.prototype.toString
    const map:any = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object',
    }
    if (obj instanceof Element) {
        return 'element'
    }
    return map[toString.call(obj)]
}


// snowflake.js
export const snowflake = () => {
    const epoch = 1609459200000; // 设定一个固定的起始时间点，例如2021-01-01
    const workerId = 0; // 工作机器ID，分配一个独一无二的数字
    const datacenterId = 0; // 数据中心ID，分配一个独一无二的数字
    let sequence = 0; // 序列号，初始值为0

    let lastTimestamp = -1;

    return function generate() {
        const currentTimestamp = Date.now();
        const timestamp = currentTimestamp - epoch;

        if (currentTimestamp < lastTimestamp) {
            // 如果时间戳比上一个ID生成的时间戳还小，则抛出错误，或者等待
            throw new Error('Clock moved backwards. Refusing to generate id');
        }

        if (lastTimestamp === timestamp) {
            // 当前毫秒没有过去，序列号自增
            sequence = (sequence + 1) & 0xFFFFFFFF;
            if (sequence === 0) {
                // 如果序列号到达最大值，等待下一个毫秒
                timestamp === Date.now();
            }
        } else {
            // 如果时间戳变了，序列号初始化
            sequence = 0;
        }

        // 记录最后一次生成ID的时间戳
        lastTimestamp = timestamp;

        // 移位合并组成64位ID
        const id = (
            (timestamp << 22) | // 时间戳占用42位
            (datacenterId << 17) | // 数据中心ID占用5位
            (workerId << 12) | // 工作机器ID占用5位
            sequence // 序列号占用12位
        );

        return id;
    };
}
